<!DOCTYPE html>
<html>
  <head>
    <title>
      Accessibility Object Model, Phase 2
    </title>
    <meta charset='utf-8'>
    <script src='https://www.w3.org/Tools/respec/respec-w3c-common' async
    class='remove'>
    </script>
    <script class='remove'>
    /*Make tidy happy*/
    var respecConfig = {
          // specification status (e.g. WD, LCWD, WG-NOTE, etc.). If in doubt use ED.
          specStatus:           "unofficial",
          // the specification's short name, as in http://www.w3.org/TR/short-name/
          shortName:            "aom",

          // if your specification has a subtitle that goes below the main
          // formal title, define it here
          // subtitle   :  "an excellent document",

          // if you wish the publication date to be other than the last modification, set this
          // publishDate:  "2009-08-06",

          // if the specification's copyright date is a range of years, specify
          // the start date here:
          // copyrightStart: "2005"

          // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
          // and its maturity status
          // previousPublishDate:  "1977-03-15",
          // previousMaturity:  "WD",

          // if there a publicly available Editor's Draft, this is the link
          // edDraftURI:           "http://berjon.com/",

          // if this is a LCWD, uncomment and set the end of its review period
          // lcEnd: "2009-08-05",

          // editors, add as many as you like
          // only "name" is required
          editors:  [
              {
                  name:       "Alice Boxhall"
              ,   url:        "http://google.com"
              ,   mailto:     "aboxhall@google.com"
              ,   company:    "Google"
              ,   companyURL: "http://google.com/"
              },
              {
                  name:       "James Craig"
              ,   url:        "http://apple.com"
              ,   mailto:     "jcraig@apple.com"
              ,   company:    "Apple"
              ,   companyURL: "http://apple.com/"
              },
              {
                  name:       "Dominic Mazzoni"
              ,   url:        "http://google.com"
              ,   mailto:     "dmazzoni@google.com"
              ,   company:    "Google"
              ,   companyURL: "http://google.com/"
              },
              {
                  name:       "Alexander Surkov"
              ,   url:        "http://mozilla.org/"
              ,   mailto:     "surkov.alexander@gmail.com"
              ,   company:    "Mozilla"
              ,   companyURL: "http://mozilla.org/"
              },
          ],
          // name of the WG
          //         wg:           "None",

          // URI of the public WG page
          //         wgURI:        "http://example.org/really-cool-wg",

          // name (without the @w3c.org) of the public mailing to which comments are due
          //          wgPublicList: "spec-writers-anonymous",

          // URI of the patent status for this WG, for Rec-track documents
          // !!!! IMPORTANT !!!!
          // This is important for Rec-track documents, do not copy a patent URI from a random
          // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
          // Team Contact.
          //        wgPatentURI:  "",
          // !!!! IMPORTANT !!!! MAKE THE ABOVE BLINK IN YOUR HEAD
      };
    </script>
  </head>
  <body>
    <section id="abstract">
      <p class="warning">
        This spec has been deprecated,
        please see the
        <a href="https://github.com/WICG/aom/blob/master/explainer.md">Accessibility Object Model Explainer</a>
        and
        <a href="index.html">index to specs</a>
        for up to date information.
      </p>
    </section>
    <section id="introduction">
      <h1>Introduction</h1>
      <p>
        This document is the spec for Phase 2 of the Accessibility Object
        Model spec. For background, please refer to the
        <a href="https://github.com/WICG/aom/blob/master/explainer.md">
          Accessibility Object Model Explainer</a> for the background and
        motivation, and then
        <a href="index.html">Phase 1</a>.
      </p>
    </section>
    <section id="actions">
      <h2>
        Phase 2: Accessible Actions
      </h2>
        <p>
          In this phase, we extend AccessibleNode so that it's also an
          EventTarget.  AccessibleNodes receive
          special <b>accessibility input events</b> or <b>accessible
          actions</b> that represent explicit intents to control the
          user agent via an accessibility API
        </p>
        <pre class="idl">
          interface AccessibleNode : EventTarget {
            ...
          };
        </pre>
        <p>
          Accessibility input events are needed for two reasons.
          <ul>
            <li>
              First, because it's possible to create AccessibleNodes
              that don't correspond to a DOM node and authors need to
              be able to listen to events on these nodes.
            </li>
            <li>
              Second,
              because there are many types of specific user intents
              that can be communicated to the user agent via accessibility
              APIs that don't correspond to existing keyboard and mouse
              events - for example some assistive technology has
              keystrokes or gestures to increment a slider, or dismiss
              a pop-up.
            </li>
          </ul>
        </p>
        <pre class="idl">
          interface AccessibleSetValueEvent : Event {
            attribute DOMString value;
          };
        </pre>
        <style>
          table{
            border:solid 2px #999;
            border-width:1px 0 0 1px;
            margin:0.1em 0 1em;
            padding:0;
            border-spacing:0;
            border-collapse:collapse;
          }
          th, td{
            border:solid 2px #999;
            border-width:0 1px 1px 0;
            padding:0.15em 0.3em 0.1em;
            vertical-align:top;
            text-align:left;
          }
          th+th, td+td{
            width:auto;
          }
          th{
            background-color:#eee;
          }
        </style>
        <table>
          <caption>
            Accessibility event table
          </caption>
          <thead>
            <tr>
              <th>event name</th>
              <th>type</th>
              <th>valid roles</th>
              <th>fallback behavior (see below)</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>"accessibleclick"</code></td>
              <td><code>Event</code></td>
              <td><em>all roles</em></td>
              <td>Fire <code>"click"</code> event on DOM node</td>
            </tr>
            <tr>
              <td><code>"accessiblefocus"</code></td>
              <td><code>Event</code></td>
              <td><em>all roles</em></td>
              <td>Focus the associated DOM element</td>
            </tr>
            <tr>
              <td><code>"accessiblesetvalue"</code></td>
              <td><code>AccessibleSetValueEvent</code></td>
              <td>
                <code>"combobox"</code>,
                <code>"scrollbar"</code>,
                <code>"slider"</code>,
                <code>"textbox"</code>
              </td>
              <td>Change value of INPUT or TEXTAREA element</td>
            </tr>
            <tr>
              <td><code>"accessibleincrement"</code></td>
              <td><code>Event</code></td>
              <td>
                <code>"scrollbar"</code>,
                <code>"slider"</code>
              </td>
              <td>
                Change value of INPUT type="range",
                otherwise fire <code>"keypress"</code> with a
                RightArrow key code
              </td>
            </tr>
            <tr>
              <td><code>"accessibledecrement"</code></td>
              <td><code>Event</code></td>
              <td>
                <code>"scrollbar"</code>,
                <code>"slider"</code>
              </td>
              <td>
                Change value of INPUT type="range",
                otherwise fire <code>"keypress"</code> with a
                LeftArrow key code
              </td>
            </tr>
            <tr>
              <td><code>"accessibleselect"</code></td>
              <td><code>Event</code></td>
              <td>
                <code>"cell"</code>,
                <code>"option"</code>
              </td>
              <td>
                Change selectedIndex of SELECT
                otherwise fire <code>"click"</code> event
              </td>
            </tr>
            <tr>
              <td><code>"accessiblescrollintoview"</code></td>
              <td><code>Event</code></td>
              <td><em>all roles</em></td>
              <td>scroll DOM node into view</td>
            </tr>
            <tr>
              <td><code>"accessibledismiss"</code></td>
              <td><code>Event</code></td>
              <td><em>all roles</em></td>
              <td>fire <code>"keypress"</code> with a
                Escape key code</td>
            </tr>
            <tr>
              <td><code>"accessiblecontextmenu"</code></td>
              <td><code>Event</code></td>
              <td><em>all roles</em></td>
              <td>fire <code>"keypress"</code> with a
                Context Menu key code, or simulate a right-click
                on the target node.</td>
            </tr>
          </tbody>
        </table>
        <p>
          Accessibility input events go through capture and bubble
          phases, just like DOM events. The only difference is that
          the capture and bubble phases happen entirely in the
          accessibility tree. If the event is not canceled
          (by calling <code>preventDefault()</code>) after completely
          going through the capture and bubble phases in the accessibility
          tree, the event executes its <dfn>fallback behavior</dfn>,
          as defined in the <a>accessibility attribute table</a>.
        </p>
        <p>
          When an event's fallback behavior involves firing a DOM
          event, the event's target will be the associated DOM node
          of the target AccessibleNode, or the associated DOM node
          of the nearest ancestor of the target AccessibleNode that
          has one. Fallback DOM events will go through capture and
          bubble phases just like any other DOM events.
        </p>
        <p>
          As an example, suppose an accessible click event is received
          on a button. Here's the sequence of what will occur:
          <ol>
            <li>Capturing event listeners are called, starting with the
              root of the accessibility tree, and continuing along the
              ancestor chain until reaching the target AccessibleNode in
              the accessibility tree.
            <li>If none of the capturing event listeners stop
              propagation, normal (non-capturing) event listeners on the
              target AccessibleNode are called, and if
              <code>stopPropagation()</code> is not called, the event
              bubbles up to all event listeners on ancestors of the
              target.
            <li>After capture and bubble phases in the accessibility tree,
              if <code>preventDefault()</code> was not called, the
              event's <a>fallback behavior</a> is triggered. In this
              case it fires a DOM <code>"click"</code> event on the
              targer AccessibleNode's associated DOM node, going through
              capture and bubble phases in the DOM tree.
          </ol>
        </p>

        <p>
          The following were considered as possible accessibility
          input events but were deferred for a future version of the
          spec. Please file a bug if you have a compelling use case
          for one of these.
        </p>
        <ul>
          <li><code>"addtoselection"</code>
          <li><code>"collapse"</code>
          <li><code>"delete"</code>
          <li><code>"expand"</code>
          <li><code>"medianext"</code>
          <li><code>"mediapause"</code>
          <li><code>"mediaprevious"</code>
          <li><code>"mediastart"</code>
          <li><code>"mediastop"</code>
          <li><code>"removefromselection"</code>
          <li><code>"scroll"</code>
          <li><code>"zoom"</code>
        </ul>
    </section>
      <section>
        <h3>Platform compatibility table</h3>

        <p>
          The following table shows proposed accessible actions and
          the native actions or methods they correspond to on each platform
          with an accessibility API.
        </p>
        <p>
          When an action maps cleanly to a method or action on all or nearly
          all platforms, that's good evidence that it's a good candidate for
          an accessible action in the Accessibility Object Model.
          When an action doesn't map cleanly, that means it's potentially
          more risky for compatibility.
        </p>
        <p>
          In the table below, Tier 1 actions appear to have broad support
          across almost all platforms. Tier 2 actions are supported on
          at least 2 unrelated platforms. The remaining native actions
          are shown below.
        </p>
        <table>
          <thead>
            <tr>
              <th>Tier</th>
              <th>Action</th>
              <th>Mac</th>
              <th>iOS</th>
              <th>MSAA + IAccessible2</th>
              <th>UIA</th>
              <th>Android</th>
              <th>ATK</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>1</td>
              <td>Activate</td>
              <td>AXPressAction</td>
              <td>accessibilityActivate</td>
              <td>IAccessible::accDoDefaultAction</td>
              <td>InvokeProvider::Invoke<br>
                IToggleProvider::Toggle
              </td>
              <td>ACTION_CLICK</td>
              <td>atk_action_do_action</td>
            </tr>
            <tr>
              <td>1</td>
              <td>Focus</td>
              <td>set AXFocused true</td>
              <td></td>
              <td>IAccessible::accSelect SELFLAG_TAKEFOCUS</td>
              <td></td>
              <td>
                ACTION_FOCUS<br>
                ACTION_CLEAR_FOCUS
              </td>
              <td>atk_component_grab_focus
              </td>
            </tr>
            <tr>
              <td>1</td>
              <td>ScrollByPage</td>
              <td></td>
              <td>accessibilityScroll</td>
              <td></td>
              <td>IScrollProvider::Scroll</td>
              <td>
                ACTION_SCROLL_BACKWARD<br>
                ACTION_SCROLL_DOWN<br>
                ACTION_SCROLL_FORWARD<br>
                ACTION_SCROLL_LEFT<br>
                ACTION_SCROLL_RIGHT<br>
                ACTION_SCROLL_UP
              </td>
              <td></td>
            </tr>
            <tr>
              <td>1</td>
              <td>ScrollIntoView</td>
              <td>
                AXScrollToVisible,<br>
                set AXVisibleCharacterRange
              </td>
              <td></td>
              <td>IAccessible2::scrollTo<br>
                IAccessibleText::scrollSubstringTo</td>
              <td>IScrollItemProvider::ScrollIntoView</td>
              <td>ACTION_SHOW_ON_SCREEN</td>
              <td></td>
            </tr>
            <tr>
              <td>1</td>
              <td>SecondaryClick</td>
              <td>AXShowMenuAction</td>
              <td>accessibilityPerformMagicTap</td>
              <td></td>
              <td></td>
              <td>
                ACTION_LONG_CLICK<br>
                ACTION_CONTEXT_CLICK
              </td>
              <td></td>
            </tr>
            <tr>
              <td>1</td>
              <td>Select</td>
              <td>
                AXPickAction<br>
                set AXSelected,<br>
                set AXSelectedChildren<br>
                set AXSelectedRows
              </td>
              <td></td>
              <td>
                IAccessible::accSelect SELFLAG_TAKESELECTION<br>
                IAccessible::accSelect SELFLAG_ADDSELECTION<br>
                IAccessible::accSelect SELFLAG_EXTENDSELECTION<br>
                IAccessible::accSelect SELFLAG_REMOVESELECTION<br>
                IAccessibleTable::selectColumn<br>
                IAccessibleTable::selectRow<br>
                IAccessibleTable::unselectColumn<br>
                IAccessibleTable::unselectRow
              </td>
              <td></td>
              <td>ACTION_SELECT</td>
              <td>
                atk_selection_add_selection<br>
                atk_selection_clear_selection<br>
                atk_selection_remove_selection<br>
                atk_selection_select_all_selection
              </td>
            </tr>
            <tr>
              <td>1</td>
              <td>SetNumericValue</td>
              <td>set AXValue</td>
              <td></td>
              <td>IAccessibleValue::setCurrentValue</td>
              <td>IRangeValueProvider::SetValue</td>
              <td>ACTION_SET_PROGRESS</td>
              <td>atk_value_set_value</td>
            </tr>
            <tr>
              <td>1</td>
              <td>SetTextValue</td>
              <td>set AXValue</td>
              <td></td>
              <td></td>
              <td>
                <br>
                IValueProvider::SetValue</td>
              <td>ACTION_SET_TEXT</td>
              <td>atk_editable_text_set_text_contents</td>
            </tr>
            <tr>
              <td>2</td>
              <td>Cancel</td>
              <td>AXCancelAction</td>
              <td>accessibilityPerformEscape</td>
              <td></td>
              <td>IWindowProvider::Close</td>
              <td>ACTION_DISMISS</td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>Collapse</td>
              <td></td>
              <td></td>
              <td></td>
              <td>IExpandCollapseProvider::Collapse</td>
              <td>ACTION_COLLAPSE</td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>CopyText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::copyText</td>
              <td></td>
              <td>ACTION_COPY</td>
              <td>atk_editable_text_copy_text</td>
            </tr>
            <tr>
              <td>2</td>
              <td>CutText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::cutText</td>
              <td></td>
              <td>ACTION_CUT</td>
              <td>atk_editable_text_cut_text</td>
            </tr>
            <tr>
              <td>2</td>
              <td>Decrement</td>
              <td>AXDecrementAction</td>
              <td>accessibilityDecrement</td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>Expand</td>
              <td></td>
              <td></td>
              <td></td>
              <td>IExpandCollapseProvider::Expand</td>
              <td>ACTION_EXPAND</td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>Increment</td>
              <td>AXIncrementAction</td>
              <td>accessibilityIncrement</td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>InsertText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::insertText</td>
              <td></td>
              <td></td>
              <td>atk_editable_text_insert_text</td>
            </tr>
            <tr>
              <td>2</td>
              <td>PasteText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::pasteText</td>
              <td></td>
              <td>ACTION_PASTE</td>
              <td>atk_editable_text_paste_text</td>
            </tr>
            <tr>
              <td>2</td>
              <td>ReplaceText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::replaceText</td>
              <td></td>
              <td></td>
              <td>
                atk_editable_text_set_text_contents,<br>
                atk_editable_text_delete_text,<br>
                atk_editable_text_insert_text
              </td>
            </tr>
            <tr>
              <td>2</td>
              <td>DeleteText</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::deleteText</td>
              <td></td>
              <td></td>
              <td>atk_editable_text_delete_text</td>
            </tr>
            <tr>
              <td>2</td>
              <td>ScrollToPoint</td>
              <td></td>
              <td></td>
              <td>
                IAccessible2::scrollToPoint<br>
                IAccessibleText::scrollSubstringToPoint
              </td>
              <td>IScrollProvider::SetScrollPercent</td>
              <td>ACTION_SCROLL_TO_POSITION</td>
              <td></td>
            </tr>
            <tr>
              <td>2</td>
              <td>
                SetSelectedTextRange
              </td>
              <td>
                set AXSelectedText<br>
                set AXSelectedTextMarkerRange<br>
                set AXSelectedTextRange
              </td>
              <td></td>
              <td>
                IAccessibleText::addSelection<br>
                IAccessibleText::removeSelection<br>
                IAccessibleText::setCaretOffset<br>
                IAccessibleText::setSelection
              </td>
              <td></td>
              <td>
                ACTION_CLEAR_SELECTION<br>
                ACTION_SET_SELECTION
              </td>
              <td>
                atk_selection_add_selection<br>
                atk_selection_clear_selection<br>
                atk_selection_remove_selection<br>
                atk_selection_select_all_selection<br>
                atk_text_add_selection<br>
                atk_text_remove_selection<br>
                atk_text_set_caret_offset
              </td>
            </tr>
            <tr>
              <td>3</td>
              <td>SetTextAttributes</td>
              <td></td>
              <td></td>
              <td>IAccessibleEditableText::setAttributes</td>
              <td></td>
              <td></td>
              <td>atk_editable_text_set_run_attributes</td>
            </tr>
          </tbody>
        </table>

        <h3>Actions unique to macOS:</h3>
        <ul>
          <li>AXConfirmAction</li>
          <li>AXDeleteAction</li>
          <li>AXRaiseAction</li>
          <li>AXShowAlternateUIAction</li>
          <li>AXShowDefaultUIAction</li>
          <li>set AXCaretBrowsingEnabled</li>
          <li>set AXDisclosing</li>
          <li>set AXGrabbed</li>
          <li>set AXPreventKeyboardDOMEventDispatch</li>
        </ul>

        <h3>Actions unique to UIA</h3>
        <ul>
          <li>IDockProvider::SetDockPosition</li>
          <li>IMultipleViewProvider::SetCurrentView</li>
          <li>ITransformProvider::Move</li>
          <li>ITransformProvider::Resize</li>
          <li>ITransformProvider::Rotate</li>
          <li>IWindowProvider::SetVisualState (minimized, maximized, normal)</li>
          </ul>

        <h3>Actions unique to Android:</h3>
        <ul>
          <li>ACTION_ACCESSIBILITY_FOCUS</li>
          <li>ACTION_CLEAR_ACCESSIBILITY_FOCUS</li>
          <li>ACTION_NEXT_AT_MOVEMENT_GRANULARITY</li>
          <li>ACTION_NEXT_HTML_ELEMENT</li>
          <li>ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY</li>
          <li>ACTION_PREVIOUS_HTML_ELEMENT</li>
        </ul>
      </section>

      <section>
        <h3>Privacy concerns</h3>
        <p>
          This phase raises some potential privacy concerns. If a web app
          receives an accessibility input event, it now knows for a fact
          that assistive technology or some other client of a native
          accessibility API is running. There is potential that this could be
          used to track or discriminate against some users.
        </p>
        <p>
          To address these concerns, a web site should not be able to
          receive these events until the user has explicitly opted in to
          allow those events to be received by that web site.
        </p>
        <p>
          A new web permission should be added, "accessibility-events", with
          a default value of "ask".
        </p>
        <p>
          A website can add event listeners to AOM nodes without triggering any
          permission checks. However, as soon as an accessibility event would
          trigger an AOM event listener, at that point the user is prompted
          to see if they want to enable the site to be able to listen for
          accessibility events.
        </p>
        <p>
          Example permission dialog text:
          <b>
            "The site www.example.com would like to
            respond to accessibility events." [Allow] [Block]
          </b>
        </p>
        <p>
          Because of the potential privacy concerns, maybe this permission should
          only be available on secure sites? Many other permissions have gone
          that route.
        </p>
      </section>
    </section>
    <section id="actions">
      <h2>
        Phase 3: Virtual Accessibility Nodes
      </h2>
      <p>See <a href="phase3.html">Phase 3</a></p>
    </section>
    <section id="actions">
      <h2>
        Phase 4: Computed Accessibility Tree
      </h2>
      <p>See <a href="phase4.html">Phase 4</a></p>
    </section>
  </body>
</html>
